package com.tiancheng.trade.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiancheng.trade.commom.core.data.PageInfo;
import com.tiancheng.trade.commom.core.data.Result;
import com.tiancheng.trade.commom.core.exception.BusinessException;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.commom.core.utils.DateTimeUtil;
import com.tiancheng.trade.order.model.RefundOrdersDetail;
import com.tiancheng.trade.order.util.SecurityUtils;
import com.tiancheng.trade.order.bo.*;
import com.tiancheng.trade.order.bo.cmq.RefundMsgBO;
import com.tiancheng.trade.order.bo.cmq.ScrmOrder;
import com.tiancheng.trade.order.enums.*;
import com.tiancheng.trade.order.feign.OrderSubSystemService;
import com.tiancheng.trade.commom.web.feign.PaymentFeignService;
import com.tiancheng.trade.commom.web.model.request.RefundDTO;
import com.tiancheng.trade.order.feign.dto.orderSubSystem.RefundQueryParamDTO;
import com.tiancheng.trade.order.mapper.RefundOrdersDetailMapper;
import com.tiancheng.trade.order.mapper.SubOrderMapper;
import com.tiancheng.trade.order.model.Order;
import com.tiancheng.trade.order.model.SubOrder;
import com.tiancheng.trade.order.service.OrderService;
import com.tiancheng.trade.order.service.RefundOrdersDetailService;
import com.tiancheng.trade.order.service.SubOrderService;
import com.tiancheng.trade.order.util.*;
import com.tiancheng.trade.order.util.cache.OrderCache;
import com.tiancheng.trade.order.util.helper.OrderIdHelper;
import com.tiancheng.trade.order.vo.admin.QueryRefundVO;
import com.tiancheng.trade.order.vo.admin.QueryTotalRefundVO;
import com.tiancheng.trade.order.vo.admin.res.RefundDetailResVO;
import com.tiancheng.trade.order.vo.admin.res.RefundResVO;
import com.tiancheng.trade.order.vo.api.ScrmOrderQueryVO;
import com.tiancheng.trade.order.vo.api.res.RefundBatchResVO;
import com.tiancheng.trade.order.vo.app.RefundQueryVO;
import com.tiancheng.trade.order.vo.app.res.RefundQueryResVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 退款Service接口实现
 *
 * @author kellen
 * @date 2024-03-18
 */
@Service
@Slf4j
public class RefundOrdersDetailServiceImpl extends ServiceImpl<RefundOrdersDetailMapper,RefundOrdersDetail> implements RefundOrdersDetailService {

    @Autowired
    private RefundOrdersDetailMapper refundOrdersDetailMapper;
    @Autowired
    private SubOrderMapper subOrderMapper;
    @Resource
    private PaymentFeignService paymentFeignService;
    @Resource
    private OrderService orderService;
    @Resource
    private SubOrderService subOrderService;
    @Resource
    private OrderIdHelper orderIdHelper;
    @Resource
    private OrderSubSystemService orderSubSystemService;

    @Override
    public RefundOrdersDetail queryRefundOrderDetailsById(Long id) {
        RefundOrdersDetail refundOrdersDetail = refundOrdersDetailMapper.selectById(id);
        return refundOrdersDetail;
    }

    @Override
    public RefundDetailResVO queryRefundOrderByRefundId(String refundId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("refund_id", refundId);
        RefundOrdersDetail refundOrdersDetail = refundOrdersDetailMapper.selectOne(conditions);
        RefundDetailResVO detailResVO = ObjectConvertUtil.convert(refundOrdersDetail, RefundDetailResVO.class).get();

        QueryWrapper<SubOrder> subOrderConditions = new QueryWrapper<SubOrder>();
        subOrderConditions.eq("sub_order_id", refundOrdersDetail.getSubOrderId());
        List<SubOrder> subOrderList = subOrderMapper.selectList(subOrderConditions);
        if (CollectionUtils.isNotEmpty(subOrderList)) {
            SubOrder subOrder = subOrderList.get(0);
            detailResVO.setSubOrderStatus(subOrder.getRefundStatus());
            detailResVO.setSubOrderStatusCN(SubOrderStatusEnum.getDesc(subOrder.getRefundStatus()));
            detailResVO.setCouponAmount(subOrder.getDiscount());
        }
        detailResVO.setOrderSourceCN(OrderSourceEnum.getDesc(refundOrdersDetail.getOrderSource()));
        detailResVO.setRefundStatusCN(RefundStatusEnum.getDesc(refundOrdersDetail.getRefundStatus()));
//        detailResVO.setSubOrderStatusCN(SubOrderStatusEnum.getDesc(refund.getSubOrderStatus()));
        return detailResVO;
    }

    @Override
    public int updateBatch(List<RefundOrdersDetailSubmitBO> submitBOS) {
        return this.baseMapper.updateBatch(submitBOS);
    }

    @Override
    public List<RefundOrdersDetail> findBySubId(String subId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("sub_order_id", subId);
        return refundOrdersDetailMapper.selectList(conditions);
    }

    @Override
    public List<RefundOrdersDetail> findSuccessBySubId(String subId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("sub_order_id", subId);
        conditions.eq("refund_status", RefundStatusEnum.success.getCode());
        return refundOrdersDetailMapper.selectList(conditions);
    }

    @Override
    public Result queryRefund(String userId, String flowId) {
        Result result = paymentFeignService.queryRefund(userId, flowId);
        log.info("订单--支付 查询退款订单 返回data：{}", JsonUtil.toJsonString(result));
        return result;
    }



    @Override
    public List<RefundOrdersDetail> getRefundForRepeatPay(String uid, RefundMsgBO refundMsgBO) throws BusinessException {
        List<SubOrder> subOrders = subOrderService.find(refundMsgBO.getOrderIds());
        List<RefundOrdersDetail> refundOrdersDetails = new ArrayList<>();
        for (SubOrder subOrder : subOrders) {
            RefundOrdersDetail refundOrdersDetail = new RefundOrdersDetail();
            refundOrdersDetail.setUid(uid);
            refundOrdersDetail.setRefundId(orderIdHelper.getRefund(uid));
            refundOrdersDetail.setPayFlowId(refundMsgBO.getPayFlowId());
            refundOrdersDetail.setOrderId(subOrder.getOrderId());
            refundOrdersDetail.setSubOrderId(subOrder.getSubOrderId());
            refundOrdersDetail.setOrderSource(subOrder.getOrderSource());
            refundOrdersDetail.setMerchantCode(subOrder.getMerchantCode());
            refundOrdersDetail.setProductCode(subOrder.getProductCode());
            refundOrdersDetail.setProductName(subOrder.getProductName());
            refundOrdersDetail.setRefundApplyAmount(subOrder.getPayAmount());
            refundOrdersDetail.setRefundAmount(subOrder.getPayAmount());
            refundOrdersDetail.setRefundStatus(RefundStatusEnum.ing.getCode());
            refundOrdersDetail.setRefundReason("重复支付，自动退款");
            refundOrdersDetail.setCreatedDt(LocalDateTime.now());
            refundOrdersDetail.setSubOrderStatus(subOrder.getSubOrderStatus());
            refundOrdersDetails.add(refundOrdersDetail);
        }
        return refundOrdersDetails;
    }

    @Override
    @Transactional
    public void saveRefundForRepeatPay(List<RefundOrdersDetail> refundOrdersDetails, RefundMsgBO refundMsgBO) {
        refundOrdersDetailMapper.saveBatch(refundOrdersDetails);

        List<Order> orders = orderService.find(refundMsgBO.getUserId(), refundMsgBO.getOrderIds());
        List<String> unusualOrderIds = new ArrayList<>();
        orders.forEach(order -> {
            // 订单状态并不是已支付，或者支付流水不同，就是异常订单
            if (!OrderStatusEnum.paid.equals(order.getOrderStatus()) || !refundMsgBO.getPayFlowId().equals(order.getFlowId())) {
                unusualOrderIds.add(order.getOrderId());
            }
        });

        // 将异常订单排除在外，不改变状态
        String[] refundSubOrderIds = refundOrdersDetails.stream().filter(refund -> !unusualOrderIds.contains(refund.getOrderId())).
                map(RefundOrdersDetail::getSubOrderId).toArray(String[]::new);
        subOrderService.refundIng(refundSubOrderIds);
    }

    @Override
    public void refundForRepeatPay(List<RefundOrdersDetail> refundOrdersDetails, RefundMsgBO refundMsgBO) throws BusinessException {
        RefundDTO refundDTO = new RefundDTO();
        refundDTO.setUid(refundMsgBO.getUserId());
        refundDTO.setPaymentId(orderIdHelper.getRefundPaymentId(refundOrdersDetails.get(0).getUid()));
        refundDTO.setPayFlowId(refundMsgBO.getPayFlowId());
        refundDTO.setAmount(refundOrdersDetails.stream().mapToInt(RefundOrdersDetail::getRefundAmount).sum());
        refundDTO.setOrderAmount(refundOrdersDetails.stream().mapToInt(RefundOrdersDetail::getRefundApplyAmount).sum());

        List<RefundDTO.SubOrderRefundDTO> subOrderRefundDTOS = new ArrayList<>();
        refundOrdersDetails.forEach(r -> {
            RefundDTO.SubOrderRefundDTO subOrderRefundDTO = new RefundDTO.SubOrderRefundDTO();
            subOrderRefundDTO.setSubOrderId(r.getSubOrderId());
            subOrderRefundDTO.setAmount(r.getRefundAmount());
            subOrderRefundDTOS.add(subOrderRefundDTO);
        });
        refundDTO.setSubOrders(subOrderRefundDTOS);

        // 调用支付中心退款
        Result result = paymentFeignService.refundOrder(refundDTO);
        log.info("退款单号:{},退款返回信息:{}", refundDTO.getPaymentId(), result);
        BusinessErrorInfoEnum.ORDER_REFUND_SERVER_ERROR.assertIsTrue(result.getRet() == 0 && result.getErrorCode() == 0, StringUtils.isNotEmpty(result.getMsg())?result.getMsg():"");

        Map<String, Object> resultMap = JsonUtil.fromJson(result.toString(), Map.class);
        Map<String, Object> dataMap = (Map<String, Object>) resultMap.get("data");

        RefundOrdersDetail updateRefundOrdersDetail = new RefundOrdersDetail();
        updateRefundOrdersDetail.setPaymentId(refundDTO.getPaymentId());
        updateRefundOrdersDetail.setFlowId(dataMap.get("flow_id").toString());

        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("uid", refundOrdersDetails.get(0).getUid());
        conditions.in("refund_id", refundOrdersDetails.stream().map(RefundOrdersDetail::getRefundId).collect(Collectors.toList()));
        refundOrdersDetailMapper.update(updateRefundOrdersDetail, conditions);
    }

    @Override
    public RefundOrdersDetail get(String refundId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("refund_id", refundId);
        return refundOrdersDetailMapper.selectOne(conditions);
    }

    @Override
    public List<RefundOrdersDetail> getRefundList(String orderId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("order_id", orderId);
        return refundOrdersDetailMapper.selectList(conditions);
    }

    /**
     * 功能描述: 退款订单查询
     *
     * @param:queryRefundVO
     * @return:
     * @auther: LiuDong
     * @date: 14:20 2024/4/2
     */
    @Override
    public PageInfo<RefundResVO> queryRefundList(QueryRefundVO queryRefundVO) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        if (null != queryRefundVO.getRefundId()) {
            conditions.eq("refund_id", queryRefundVO.getRefundId());
        }
        if (null != queryRefundVO.getPaymentId()) {
            conditions.eq("payment_id", queryRefundVO.getPaymentId());
        }
        if (null != queryRefundVO.getOrderId()) {
            conditions.eq("order_id", queryRefundVO.getOrderId());
        }
        if (null != queryRefundVO.getSubOrderId()) {
            conditions.eq("sub_order_id", queryRefundVO.getSubOrderId());
        }
        if (null != queryRefundVO.getMerchantCode()) {
            conditions.eq("merchant_code", queryRefundVO.getMerchantCode());
        }
        if (null != queryRefundVO.getMerchantName()) {
            conditions.like("merchant_name", queryRefundVO.getMerchantName());
        }
        if (null != queryRefundVO.getOrderSource()) {
            conditions.eq("order_source", queryRefundVO.getOrderSource());
        }
        if (null != queryRefundVO.getRefundStatus()) {
            conditions.eq("refund_status", queryRefundVO.getRefundStatus());
        }
        if (!StringUtils.isEmpty(queryRefundVO.getCreateTimeBegin()) && !StringUtils.isEmpty(queryRefundVO.getCreateTimeEnd())) {
            conditions.between("created_dt", DateTimeUtil.format(queryRefundVO.getCreateTimeBegin() + " 00:00:00", "yyyy-MM-dd HH:mm:ss"),
                    DateTimeUtil.format(queryRefundVO.getCreateTimeEnd() + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
        }
        if (!StringUtils.isEmpty(queryRefundVO.getRefundTimeBegin()) && !StringUtils.isEmpty(queryRefundVO.getRefundTimeEnd())) {
            conditions.between("refund_time", DateTimeUtil.format(queryRefundVO.getRefundTimeBegin() + " 00:00:00", "yyyy-MM-dd HH:mm:ss"),
                    DateTimeUtil.format(queryRefundVO.getRefundTimeEnd() + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
        }
        conditions.orderByDesc("created_dt");
        PageInfo<RefundOrdersDetail> refunds = refundOrdersDetailMapper.find(conditions, queryRefundVO.getCurrentPage(), queryRefundVO.getPageSize());
        List<RefundResVO> vos = refunds.getList().stream().map(refund ->
                ObjectConvertUtil.convert(refund, RefundResVO.class).get()).collect(Collectors.toList());
        vos.stream().forEach(refundResVO -> refundResVO.setOrderSourceCN(OrderSourceEnum.getDesc(refundResVO.getOrderSource())));
        vos.stream().forEach(refundResVO -> refundResVO.setRefundStatus(RefundStatusEnum.getDesc(refundResVO.getRefundStatus())));
        PageInfo<RefundResVO> pageInfo = new PageInfo<>();
        pageInfo.setList(vos);
        pageInfo.setPagination(refunds.getPagination());
        return pageInfo;
    }

    @Override
    public Map<String, Long> queryTotal(QueryTotalRefundVO queryTotalRefundVO) {
        if (StringUtils.isEmpty(queryTotalRefundVO.getStartDate())) {
            queryTotalRefundVO.setStartDate(DateTimeUtil.format(LocalDate.now().plusMonths(-1), "yyyy-MM-dd"));
        }
        if (StringUtils.isEmpty(queryTotalRefundVO.getEndDate())) {
            queryTotalRefundVO.setEndDate(DateTimeUtil.format(LocalDate.now(), "yyyy-MM-dd"));
        }
        if (StringUtils.isEmpty(queryTotalRefundVO.getRefundStatus())) {
            queryTotalRefundVO.setRefundStatus(RefundStatusEnum.success.getCode());
        }
        return refundOrdersDetailMapper.queryTotal(Arrays.asList(queryTotalRefundVO.getRefundStatus()),
                DateTimeUtil.format(queryTotalRefundVO.getStartDate() + " 00:00:00", "yyyy-MM-dd HH:mm:ss"),
                DateTimeUtil.format(queryTotalRefundVO.getEndDate() + " 23:59:59", "yyyy-MM-dd HH:mm:ss"));
    }

    @Override
    public List<RefundOrdersDetail> getSubRefund(String suborderId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("sub_order_id", suborderId);
        return refundOrdersDetailMapper.selectList(conditions);
    }

    @Override
    public PageInfo<RefundQueryResVO> findForApp(RefundQueryVO refundQueryVO) {
        String uid = SecurityUtils.getLoginUserId();

        // 如果是下一页数据，就添加一个时间条件
        Optional<String> time = Optional.empty();
        if (refundQueryVO.getPage() > 1) {
            time = OrderCache.getQueryOrderNextTime(uid);
        }

        // 查询php版订单系统的用户数据
        RefundQueryParamDTO queryParamDTO = new RefundQueryParamDTO();
        queryParamDTO.setUserId(uid);
        queryParamDTO.setPage(1);
        queryParamDTO.setPageSize(refundQueryVO.getSize());
        if (time.isPresent()) {
            queryParamDTO.setEndAt(time.get());
        }
        List<Map<String, Object>> future = orderSubSystemService.findRefundByUser(queryParamDTO);

        // 查询本系统的用户退款单数据
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("uid", uid);
        if (time.isPresent()) {
            conditions.lt("created_dt", time.get());
        }
        conditions.orderByDesc("created_dt");
        PageInfo<RefundOrdersDetail> refunds = refundOrdersDetailMapper.find(conditions, 1, refundQueryVO.getSize());

        List<RefundQueryResVO> resRefunds = new ArrayList<>();
        for (RefundOrdersDetail refundOrdersDetail : refunds.getList()) {
            Order order = orderService.get(refundOrdersDetail.getOrderId());
            OrderSourceEnum orderSourceEnum = EnumUtil.getEnumByCode(OrderSourceEnum.class, refundOrdersDetail.getOrderSource());
            RefundQueryResVO resVO = new RefundQueryResVO();
            resVO.setOrderId(refundOrdersDetail.getOrderId());
            resVO.setSubOrderId(refundOrdersDetail.getSubOrderId());
            resVO.setRefundId(refundOrdersDetail.getPaymentId());
            resVO.setMerchantCode(refundOrdersDetail.getMerchantCode());
            resVO.setProductName(refundOrdersDetail.getProductName());
            resVO.setOrderSource(refundOrdersDetail.getOrderSource());
            resVO.setOrderSourceName(orderSourceEnum.name().toLowerCase());
            resVO.setOrderSourceCn(orderSourceEnum.desc());
            resVO.setStatus(refundOrdersDetail.getRefundStatus());
            resVO.setStatusName(EnumUtil.getEnumByCode(RefundStatusEnum.class, resVO.getStatus()).getDesc());
            resVO.setRefundAmount(new BigDecimal(refundOrdersDetail.getRefundAmount()).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP));
            resVO.setDescription(refundOrdersDetail.getRefundReason());
            resVO.setCreateTime(refundOrdersDetail.getCreatedDt());
            resVO.setRefundTime(refundOrdersDetail.getRefundTime());
            resVO.setIsPlatformOrder(true);
            if (orderSourceEnum == OrderSourceEnum.FLIGHT) {
                resVO.setFlightInfo(order != null && !StringUtils.isEmpty(order.getTradeInfo()) ? JsonUtil.fromJson(order.getTradeInfo(), Map.class) : null);
            }
            resVO.setBatchDesc(OrderParallelUtil.getBatchDesc(orderSourceEnum, order.getTradeInfo()));
            resRefunds.add(resVO);
        }

        try {
            for (Map<String, Object> refund : future) {
                RefundQueryResVO resVO = new RefundQueryResVO();
                resVO.setOrderId(String.valueOf(refund.get("order_id")));
                resVO.setSubOrderId(String.valueOf(refund.get("sub_order_id")));
                resVO.setRefundId(String.valueOf(refund.get("refund_id")));
                resVO.setMerchantCode(String.valueOf(refund.get("merchant_id")));
                resVO.setProductName(String.valueOf(refund.get("goods_name")));
                resVO.setOrderSource(String.valueOf(refund.get("order_type")));
                resVO.setOrderSourceName(String.valueOf(refund.get("type_name")));
                resVO.setOrderSourceCn(EnumUtil.getEnumByCode(OrderSourceEnum.class, resVO.getOrderSource()).desc());
                resVO.setStatus(String.valueOf(refund.get("status")));
                resVO.setStatusName(String.valueOf(refund.get("status_name")));
                resVO.setRefundAmount(new BigDecimal(String.valueOf(refund.get("refund_amount_yuan"))));
                resVO.setDescription(String.valueOf(refund.get("description")));
                resVO.setCreateTime(DateTimeUtil.format(String.valueOf(refund.get("create_time")), "yyyy-MM-dd HH:mm:ss"));
                resVO.setRefundTime(DateTimeUtil.format(String.valueOf(refund.get("update_time")), "yyyy-MM-dd HH:mm:ss"));
                resVO.setIsPlatformOrder(Boolean.valueOf(String.valueOf(refund.get("is_platform_order"))));
                resVO.setFlightInfo(refund.containsKey("flight_info") ? refund.get("flight_info") : null);
                resVO.setBatchDesc(String.valueOf(refund.get("batch_desc")));
                resRefunds.add(resVO);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        // 将两套系统的数据再排序，取指定条数
        resRefunds = resRefunds.stream().sorted(Comparator.comparing(RefundQueryResVO::getCreateTime).reversed()).collect(Collectors.toList());
        resRefunds = resRefunds.subList(0, refundQueryVO.getSize() > resRefunds.size() ? resRefunds.size() : refundQueryVO.getSize());

        PageInfo<RefundQueryResVO> pageInfo = new PageInfo<>(resRefunds, new PageInfo.Pagination(refundQueryVO.getPage(),
                refundQueryVO.getSize(), refundQueryVO.getSize()));

        // 缓存下一页的查询时间点
        if (resRefunds.size() > 0) {
            LocalDateTime nextTime = resRefunds.get(resRefunds.size() - 1).getCreateTime();
            OrderCache.queryOrderNextTime(uid, DateTimeUtil.format(nextTime, "yyyy-MM-dd HH:mm:ss"));
        }
        return pageInfo;
    }

    @Override
    public RefundBatchResVO getByPaymentId(String uid, String paymentId) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("uid", uid);
        conditions.eq("payment_id", paymentId);

        List<RefundOrdersDetail> refundOrdersDetails = refundOrdersDetailMapper.selectList(conditions);
        if (refundOrdersDetails.size() > 0) {
            RefundBatchResVO resVO = new RefundBatchResVO();
            resVO.setOrderId(refundOrdersDetails.get(0).getOrderId());
            resVO.setPaymentId(paymentId);
            resVO.setUid(uid);
            resVO.setRefundReason(refundOrdersDetails.get(0).getRefundReason());
            resVO.setRefundAmount(refundOrdersDetails.stream().mapToInt(RefundOrdersDetail::getRefundAmount).sum());
            resVO.setStatus(refundOrdersDetails.get(0).getRefundStatus());
            resVO.setCreateTime(refundOrdersDetails.get(0).getCreatedDt());
            resVO.setRefundTime(refundOrdersDetails.get(0).getRefundTime());
            return resVO;
        }
        return null;
    }

    @Override
    public List<RefundOrdersDetail> querySuccessRefundBySubOrderIds(Set<String> orderIds, Set<String> subOrderIds) {
        if (CollectionUtils.isNotEmpty(subOrderIds)) {
            QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
            conditions.in("order_id", orderIds);
            conditions.in("sub_order_id", subOrderIds);
            conditions.eq("refund_status", RefundStatusEnum.success.getCode());
            return this.refundOrdersDetailMapper.selectList(conditions);
        }
        return null;
    }

    @Override
    public List<RefundOrdersDetail> saveApplePayResult(RefundNotifyBO refundNotifyBO) {
        boolean success = "success".equalsIgnoreCase(refundNotifyBO.getStatus());

        BusinessErrorInfoEnum.ORDER_REFUND_NO_DATA.assertIsTrue(!StringUtils.isEmpty(refundNotifyBO.getPaymentId()) &&
                !StringUtils.isEmpty(refundNotifyBO.getPayFlowId()));

        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.eq("payment_id", refundNotifyBO.getPaymentId());
        List<RefundOrdersDetail> refundOrdersDetails = refundOrdersDetailMapper.selectList(conditions);
        if (CollectionUtils.isEmpty(refundOrdersDetails)) {
            // 没有退款单，创建
            refundOrdersDetails = new ArrayList<>(1);
            if (StringUtils.isEmpty(refundNotifyBO.getPayFlowId())) {
                log.error("苹果退款回调，未查询到订单，pay_flow_id:{}", refundNotifyBO.getPayFlowId());
                return null;
            }
            final Order order = orderService.findByFlowId(refundNotifyBO.getPayFlowId());
            if (null == order) {
                log.error("苹果退款回调，未查询到订单，pay_flow_id:{}", refundNotifyBO.getPayFlowId());
                return null;
            }
            final List<SubOrder> subOrders = subOrderService.findByOrderId(order.getOrderId());
            List<RefundOrdersDetail> finalRefundOrdersDetails = refundOrdersDetails;
            subOrders.forEach(s -> {
                RefundOrdersDetail refundOrdersDetail = new RefundOrdersDetail();
                refundOrdersDetail.setUid(order.getUid());
                refundOrdersDetail.setRefundId(orderIdHelper.getRefund(order.getOrderSource(), order.getUid()));
                refundOrdersDetail.setPaymentId(refundNotifyBO.getPaymentId());
                refundOrdersDetail.setPayFlowId(refundNotifyBO.getFlowId());
                refundOrdersDetail.setOrderId(order.getOrderId());
                refundOrdersDetail.setSubOrderId(s.getSubOrderId());
                refundOrdersDetail.setOrderSource(s.getOrderSource());
                refundOrdersDetail.setMerchantCode(s.getMerchantCode());
                refundOrdersDetail.setMerchantName(s.getMerchantName());
                refundOrdersDetail.setProductCode(s.getProductCode());
                refundOrdersDetail.setProductName(s.getProductName());
                refundOrdersDetail.setDiscount(0);
                refundOrdersDetail.setPlatformDiscount(0);
                refundOrdersDetail.setRefundApplyAmount(s.getSubOrderAmount());
                refundOrdersDetail.setRefundAmount(s.getSubOrderAmount()); // 实际退款金额=申请退款金额-应退优惠
                refundOrdersDetail.setSubOrderAmount(s.getSubOrderAmount());
                refundOrdersDetail.setSubOrderPayAmount(s.getPayAmount());
                refundOrdersDetail.setRefundStatus(success ? RefundStatusEnum.success.getCode() : RefundStatusEnum.fail.getCode());
                refundOrdersDetail.setRefundReason("用户申请退款");
                refundOrdersDetail.setCreatedDt(refundNotifyBO.getRefundTime());
                refundOrdersDetail.setRefundTime(refundNotifyBO.getRefundTime());
                refundOrdersDetail.setSubOrderStatus(s.getSubOrderStatus());
                refundOrdersDetail.setFlowId(refundNotifyBO.getFlowId());
                finalRefundOrdersDetails.add(refundOrdersDetail);
            });
            refundOrdersDetails = finalRefundOrdersDetails;
            refundOrdersDetailMapper.saveBatch(finalRefundOrdersDetails);
        } else {
            // 已有退款单，更新状态
            if (refundOrdersDetails.get(0).getRefundStatus().equals(RefundStatusEnum.success.getCode())) {
                BusinessErrorInfoEnum.ORDER_REFUND_REPEAT_NOTICE.assertFail();
            }
            RefundOrdersDetail updateRefundOrdersDetail = new RefundOrdersDetail();
            updateRefundOrdersDetail.setFlowId(refundNotifyBO.getFlowId());
            updateRefundOrdersDetail.setRefundTime(refundNotifyBO.getRefundTime());
            updateRefundOrdersDetail.setRefundStatus(success ? RefundStatusEnum.success.getCode() : RefundStatusEnum.fail.getCode());
            refundOrdersDetailMapper.update(updateRefundOrdersDetail, conditions);
        }

        // 修改订单状态
        String orderId = refundOrdersDetails.get(0).getOrderId();
        List<SubOrderRefundBO> subOrderRefundBOS = new ArrayList<>();
        for (RefundOrdersDetail refundOrdersDetail : refundOrdersDetails) {
            String refundStatus = success ? RefundStatusEnum.success.getCode() : RefundStatusEnum.fail.getCode();
            Integer subOrderRefundAmount = success ? refundOrdersDetail.getRefundAmount() : 0;
            subOrderRefundBOS.add(new SubOrderRefundBO(orderId, refundOrdersDetail.getSubOrderId(), subOrderRefundAmount, refundStatus));
        }
        orderService.refund(success, orderId, subOrderRefundBOS);
        refundOrdersDetails.forEach(refund -> {
            refund.setRefundTime(refundNotifyBO.getRefundTime());
            refund.setRefundStatus(success ? RefundStatusEnum.success.getCode() : RefundStatusEnum.fail.getCode());
            refund.setFlowId(refundNotifyBO.getFlowId());
        });
        return refundOrdersDetails;
    }

    @Override
    public PageInfo<ScrmOrder> queryPayOrderAndSubOrder(ScrmOrderQueryVO queryVO) {
        QueryWrapper<RefundOrdersDetail> conditions = new QueryWrapper<>();
        conditions.in("order_source", queryVO.getOrderSource().split(","));

        // 默认最多查询一个月的订单
        if (queryVO.getCreateTimeBegin()!=null && queryVO.getCreateTimeEnd()!=null) {
            conditions.between("created_dt", queryVO.getCreateTimeBegin(), queryVO.getCreateTimeEnd());
        }
        if(!StringUtils.isEmpty(queryVO.getUid())){
            conditions.eq("uid",queryVO.getUid());
        }
        conditions.eq("refund_status",RefundStatusEnum.success.getCode());
        conditions.select("id","order_id","sub_order_id");
        PageInfo<RefundOrdersDetail> refunds = refundOrdersDetailMapper.find(conditions, queryVO.getPage(), queryVO.getSize());
        PageInfo<ScrmOrder> result=new PageInfo<>(null,refunds.getPagination());
        if(CollectionUtils.isNotEmpty(refunds.getList())){
            final List<ScrmOrder> scrmOrders = orderService.queryScrmOrderBySubOrders(refunds.getList().stream().map(RefundOrdersDetail::getSubOrderId).collect(Collectors.toSet()));
            scrmOrders.forEach(o-> o.getChildOrderList().forEach(c->{
                final Optional<RefundOrdersDetail> first = refunds.getList().stream().filter(r -> r.getSubOrderId().equals(c.getChildOrderId())).findFirst();
                if(first.isPresent()){
                    c.setOrderStatus("Trade_Canceled");
                    c.setRefundId(first.get().getId().intValue());
                    c.setRefundStatus("RefundSuccess");
                }
            }));
            result.setList(scrmOrders);
            result.setPagination(refunds.getPagination());
        }
        return result;
    }

    @Override
    public List<RefundOrdersDetail> queryByRefundId(String refundId) {
        return refundOrdersDetailMapper.selectList(new LambdaQueryWrapper<RefundOrdersDetail>().eq(RefundOrdersDetail::getRefundId,refundId));
    }

}
